package com.zxf.basic.expand

import android.annotation.SuppressLint
import android.app.Activity
import android.app.ActivityManager
import android.app.NotificationManager
import android.content.ClipboardManager
import android.content.Context
import android.content.Intent
import android.location.LocationManager
import android.net.ConnectivityManager
import android.net.wifi.WifiManager
import android.os.PowerManager
import android.view.Gravity
import android.view.WindowManager
import android.widget.Toast
import androidx.activity.result.ActivityResult
import androidx.activity.result.ActivityResultLauncher
import androidx.activity.result.contract.ActivityResultContracts
import androidx.appcompat.app.AppCompatActivity
import androidx.fragment.app.Fragment
import androidx.lifecycle.ViewModel
import androidx.lifecycle.ViewModelProvider

/**
 * Context扩展
 *
 * @author Jack 2021-05-01 18:38
 */
fun Context.toast(msg: String?) {
    msg?.apply {
        val toast = Toast.makeText(this@toast, this, Toast.LENGTH_SHORT)
        toast.setGravity(Gravity.CENTER, 0, 0)
        toast.show()
    }
}

inline fun <reified A : Activity> Activity.newIntent(block: Intent.() -> Unit): Intent {
    val intent = Intent(this, A::class.java)
    block.invoke(intent)
    return intent
}

inline fun <reified A : Activity> Fragment.newIntent(block: Intent.() -> Unit): Intent {
    val intent = Intent(requireActivity(), A::class.java)
    block.invoke(intent)
    return intent
}

fun newIntent(block: Intent.() -> Unit): Intent {
    val intent = Intent()
    block.invoke(intent)
    return intent
}

inline fun <reified A : Activity> Fragment.startActivity(block: Intent.() -> Unit) {
    val intent = Intent(requireActivity(), A::class.java)
    intent.also(block)
    requireActivity().startActivity(intent)
}

inline fun <reified A : Activity> Activity.startActivity(block: Intent.() -> Unit) {
    val intent = Intent(this, A::class.java)
    intent.also(block)
    startActivity(intent)
}

fun Fragment.startActivityResult(block: (result: ActivityResult) -> Unit): ActivityResultLauncher<Intent> {
    return registerForActivityResult(ActivityResultContracts.StartActivityForResult()) {
        block.invoke(it)
    }
}

inline fun <reified A : Activity> ActivityResultLauncher<Intent>.launch(context: Context, block: Intent.() -> Unit) {
    val intent = Intent(context, A::class.java)
    block.invoke(intent)
    launch(intent)
}

inline fun <reified A : Activity> AppCompatActivity.startActivityResult(intent: Intent.() -> Unit, crossinline block: (result: ActivityResult) -> Unit) {
    val myIntent = Intent(this, A::class.java)
    myIntent.also(intent)
    registerForActivityResult(ActivityResultContracts.StartActivityForResult()) {
        block.invoke(it)
    }.launch(myIntent)
}

inline fun <reified A : Activity> Context.startActivity(block: Intent.() -> Unit) {
    val intent = Intent(this, A::class.java)
    intent.flags = Intent.FLAG_ACTIVITY_NEW_TASK
    intent.also(block)
    startActivity(intent)
}

/**
 * 给Context拓展获取关于Context Service的manager
 */
@SuppressLint("ServiceCast")
inline fun <reified T> Context.systemService(): T {
    val clz = T::class
    return when (clz) {
        ConnectivityManager::class -> applicationContext.getSystemService(Context.CONNECTIVITY_SERVICE) as T
        ActivityManager::class -> applicationContext.getSystemService(Context.ACTIVITY_SERVICE) as T
        WifiManager::class -> applicationContext.getSystemService(Context.WIFI_SERVICE) as T
        PowerManager::class -> applicationContext.getSystemService(Context.POWER_SERVICE) as T
        NotificationManager::class -> applicationContext.getSystemService(Context.NOTIFICATION_SERVICE) as T
        ClipboardManager::class -> applicationContext.getSystemService(Context.CLIPBOARD_SERVICE) as T
        WindowManager::class -> applicationContext.getSystemService(Context.WINDOW_SERVICE) as T
        LocationManager::class -> applicationContext.getSystemService(Context.LOCATION_SERVICE) as T
        else -> {
            throw IllegalArgumentException("can not find class")
        }
    }
}

/**
 * 获取viewmodel
 */
inline fun <reified VM : ViewModel> AppCompatActivity.viewModel() = ViewModelProvider(this)[VM::class.java]

inline fun <reified VM : ViewModel> Fragment.viewModel() = ViewModelProvider(this)[VM::class.java]